const MongoClient = require("mongodb").MongoClient;
const MongoDB = require("mongodb");
const UUID = require("uuid");
let config = require('../../config');

const url = config.dbpath; 
// const url = "mongodb://106.55.50.108:27017/db01";
let dbo;
MongoClient.connect(url, (err, db) => {
    if (err) {
        console.log(err);
        console.info("数据库创建失败!");
    } else {
        console.info("数据库已创建!");
        dbo = db.db("plan");
    }
});

class DB {
    constructor() {}
    addLookup(from, localField, foreignField, as) {
        return {
            $lookup: {
                from,
                localField,
                foreignField,
                as,
            },
        }
    }

    addUnwind(path) {
        return {
            $unwind: {
                path, //'$userInfo',
                preserveNullAndEmptyArrays: true,
            }
        }
    }



    test() {
        return new Promise((resolve, reject) => {
            dbo.collection('scores').aggregate([{
                    $match: {
                        // userId: MongoDB.ObjectId("621f803b39063d078fdab444")
                        // score: 10
                    }
                },
                {
                    $lookup: {
                        from: 'projects',
                        localField: 'projId',
                        foreignField: '_id',
                        as: 'projInfo'
                    },
                },
                {
                    $lookup: {
                        from: 'users',
                        localField: 'userId',
                        foreignField: '_id',
                        as: 'userInfo'
                    },
                },
                // {
                //   $unwind: {
                //     path: '$userInfo',
                //     preserveNullAndEmptyArrays: true,
                //   }
                // },
                // {
                //   $project: {
                //     "_id": 1,
                //     "userId": 1,
                //     "cTime": 1,
                //     "uTime": 1,
                //     "score": 1,
                //     "scores": 1,
                //     "projId": 1, 
                //     'userInfo.username': 1,
                //     'userInfo.username': 1,
                //     'userInfo.pinyin': 1,
                //   }
                // }
            ]).toArray((err, res) => {
                if (err) {
                    reject(err);
                } else {
                    resolve(res);
                }
            })
        })
    }

    // 两表联合查询
    uniteQuery(originColl, options) {
        let arr = [
            ...options,
        ]
        return dbo.collection(originColl).aggregate(options).toArray();
    }

    findOne(collName, query) {
        return new Promise((resolve, reject) => {
            dbo
                .collection(collName)
                .find(query)
                .toArray((err, result) => {
                    if (err) {
                        ('err', err);
                        reject(err);
                    } else {
                        resolve(result[0]);
                    }
                });
        });
    }

    findOneById(collName, id) {
        let query = {
            _id: MongoDB.ObjectId(id)
        }
        return new Promise((resolve, reject) => {
            dbo
                .collection(collName)
                .find(query)
                .toArray((err, result) => {
                    if (err) {
                        reject(err);
                    } else {
                        resolve(result[0]);
                    }
                });
        });
    }

    count(collName, query = {}) {
        return new Promise(async (resolve, reject) => {
            try {
                let res = await dbo.collection(collName).find(query).count();
                resolve(res);
            } catch (error) {
                reject(error);
            }
        })
    }

    findList(collName, query = {}) {
        return new Promise((resolve, reject) => {
            dbo
                .collection(collName)
                .find(query)
                .toArray((err, result) => {
                    if (err) {
                        reject(err);
                    } else {
                        resolve(result);
                    }
                });
        });
    }

    findListByPage(collName, pageSize, currPage, query = {}) {
        return new Promise((resolve, reject) => {
            let skipNum = (currPage - 1) * pageSize;
            dbo
                .collection(collName)
                .find(query).skip(skipNum).limit(pageSize)
                .toArray((err, result) => {
                    if (err) {
                        reject(err);
                    } else {
                        resolve(result);
                    }
                });
        });
    }

    // 包含某个属性
    findListByAttr(collName, attr) {
        let query = {
            [attr]: {
                $regex: "."
            },
        };
        return new Promise((resolve, reject) => {
            dbo
                .collection(collName)
                .find(query)
                .toArray((err, result) => {
                    if (err) {
                        reject(err);
                    } else {
                        resolve(result);
                    }
                });
        });
    }

    all(collName) {
        return new Promise((resolve, reject) => {
            dbo
                .collection(collName)
                .find({})
                .toArray(function (err, result) {
                    if (err) {
                        reject(err);
                    } else {
                        resolve(result);
                    }
                });
        });
    }

    insertOne(collName, data) {
        data.cTime = Date.now();
        data.uTime = Date.now();
        return new Promise((resolve, reject) => {
            dbo.collection(collName).insertOne(data, (err, res) => {
                if (err) {
                    console.log(err);
                    reject(err);
                } else {
                    resolve(data);
                }
            });
        });
    }

    insertMany(collName, data) {
        return new Promise((resolve, reject) => {
            dbo.collection(collName).insertMany(data, (err, res) => {
                if (err) {
                    reject(err);
                } else {
                    resolve(data);
                }
            });
        });
    }

    deleteById(collName, where) {
        return new Promise((resolve, reject) => {
            let whereStr = {
                _id: MongoDB.ObjectId(where._id),
            };
            dbo.collection(collName).deleteOne(whereStr, function (err, obj) {
                if (err) {
                    reject(err);
                } else {
                    resolve(obj);
                }
            });
        });
    }

    deleteOne(collName, where) {
        return new Promise((resolve, reject) => {
            dbo.collection(collName).deleteOne(where, function (err, obj) {
                if (err) {
                    reject(err);
                } else {
                    resolve(obj);
                }
            });
        });
    }

    deleteMany(collName, whereStr) {
        (collName, whereStr);
        return new Promise((resolve, reject) => {
            dbo.collection(collName).deleteMany(whereStr, function (err, obj) {
                if (err) {
                    reject(err);
                } else {
                    resolve(obj);
                }
            });
        });
    }

    updateById(collName, _id, updateStr) {
        let whereStr = {
            _id: MongoDB.ObjectId(_id),
        };
        return this.updateOne(collName, whereStr, updateStr);
    }

    updateOne(collName, whereStr, updateStr) {
        updateStr = {
            $set: updateStr,
        };
        return new Promise((resolve, reject) => {
            dbo.collection(collName).updateOne(whereStr, updateStr, (err, res) => {
                if (err) {
                    reject(err);
                } else {
                    resolve(res);
                }
            });
        });
    }
}

module.exports = new DB();